module.exports = function(grunt) {
  grunt.registerTask('generate-scss-metadata', async function() {
    const fs = require('fs').promises;
    const path = require('path');
    const imageSize = require('image-size');
    const done = this.async();

    const findMostFrequentNumber = (arr) => {
      const counts = arr.reduce((acc, num) => {
          acc[num] = (acc[num] || 0) + 1;
          return acc;
      }, {});

      return Object.keys(counts).reduce((a, b) => counts[a] > counts[b] ? a : b);
    }

    try {
      const fileWarning = "// ! DO NOT EDIT This file is autogenerated DO NOT EDIT !//"
      const flagsPath = 'src/img/flags/@1x';
      const outputFile = 'src/css/_metadata.scss';
      const spriteFile1x = "build/img/flags.png"
      const spriteFile2x = "build/img/flags@2x.png"
      let outputFileContent = ''

      let allFlagWidths = [];
      let allFlagHeights = [];
      let uniqueFlagWidths = [];
      let uniqueFlagHeights = [];

      let offset = 0;
      const flagMargin = 2;

      const spritePath1x = path.join(spriteFile1x);
      const sprite1xDimensions = await imageSize(spritePath1x);
      let sprite1xMetadata = "";
      sprite1xMetadata += "$flags-sprite-1x: (\n";
      sprite1xMetadata += `  height: ${sprite1xDimensions.height}px,\n`;
      sprite1xMetadata += `  width: ${sprite1xDimensions.width}px,\n`;
      sprite1xMetadata += ");";

      const spritePath2x = path.join(spriteFile2x);
      const sprite2xDimensions = await imageSize(spritePath2x);
      let sprite2xMetadata = "";
      sprite2xMetadata += "$flags-sprite-2x: (\n";
      sprite2xMetadata += `  height: ${sprite2xDimensions.height}px,\n`;
      sprite2xMetadata += `  width: ${sprite2xDimensions.width}px,\n`;
      sprite2xMetadata += ");";

      const files = await fs.readdir(flagsPath);
      let flagsMetadata = "$flags: (\n";
      for (const file of files) {
        if (file.endsWith('.png')) {
          const name = path.parse(file).name.toLowerCase();
          const imagePath = path.join(flagsPath, file);
          const { width, height } = await imageSize(imagePath);
          const pxWidth = `${width}px`;
          const pxHeight = `${height}px`;
          const pxOffset = `${offset}px`;

          flagsMetadata += `  ${name}: (\n`;
          flagsMetadata += `    width: ${pxWidth},\n`;
          flagsMetadata += `    height: ${pxHeight},\n`;
          flagsMetadata += `    offset: ${pxOffset},\n`;
          flagsMetadata += "  ),\n";

          allFlagWidths.push(pxWidth)
          allFlagHeights.push(pxHeight);

          if (!uniqueFlagWidths.includes(pxWidth)) uniqueFlagWidths.push(pxWidth);
          if (!uniqueFlagHeights.includes(pxHeight)) uniqueFlagHeights.push(pxHeight);

          offset = offset - width - flagMargin;
        }
      }
      flagsMetadata += ");";

      const flagsMostCommonWidth = `$most-common-flag-width: ${findMostFrequentNumber(allFlagWidths)};`
      const flagsMostCommonHeight = `$most-common-flag-height: ${findMostFrequentNumber(allFlagHeights)};`
      const flagsUniqueWidthsMetadata = `$unique-flag-widths: (${uniqueFlagWidths.sort().join(', ')});`;
      const flagsUniqueHeightsMetadata = `$unique-flag-heights: (${uniqueFlagHeights.sort().join(', ')});`;

      outputFileContent += fileWarning
      outputFileContent += "\n\n"
      outputFileContent += sprite1xMetadata
      outputFileContent += "\n\n"
      outputFileContent += sprite2xMetadata
      outputFileContent += "\n\n"
      outputFileContent += flagsMostCommonWidth
      outputFileContent += "\n\n"
      outputFileContent += flagsMostCommonHeight
      outputFileContent += "\n\n"
      outputFileContent += flagsUniqueWidthsMetadata
      outputFileContent += "\n\n"
      outputFileContent += flagsUniqueHeightsMetadata
      outputFileContent += "\n\n"
      outputFileContent += flagsMetadata
      outputFileContent += "\n\n"
      outputFileContent += fileWarning
      outputFileContent += "\n"

      await fs.writeFile(outputFile, outputFileContent);
      console.log('SCSS file generated successfully.');
      done();
    } catch (error) {
      console.error('Error:', error);
      done(error);
    }
  });
};
